package gateway.mgt

import com.amihaiemil.camel.Yaml
import gateway.mgt.api.ratelimit.RateLimitStrategy
import grails.testing.gorm.DomainUnitTest
import spock.lang.Specification

class RateLimitStrategySpec extends Specification implements DomainUnitTest<RateLimitStrategy> {

    static final ValidPropertiesSet = [
            [name: "demo", apiLimit: 200L],
            [name: "demo", apiLimit: 200L, userLimit: 150L, appLimit: 100L]
    ]

    static final InvalidPropertiesSet = [
            [
                    name: "demo", expected_error_counter: 1
            ],
            [
                    name: "demo", apiLimit: 200L, userLimit: 300L, expected_error_counter: 1
            ]
    ]

    def setup() {
    }

    def cleanup() {
    }

    void "test a valid properties"() {
        given:
        def instance = new RateLimitStrategy(params)

        when:
        instance.save(flush: true)

        then:
        !instance.hasErrors()

        where:
        params << ValidPropertiesSet
    }

    void "test an invalid properties"() {
        given:
        def instance = new RateLimitStrategy(params)

        when:
        instance.save(flush: true)

        then:
        instance.hasErrors()

        and:
        instance.errors.allErrors.size() == params.expected_error_counter

        where:
        params << InvalidPropertiesSet
    }

    void "test method: Pluggable#plug(Map)"() {
        given:
        def instance = new RateLimitStrategy(name: "demo", apiLimit: 200L)
        def routeElements = [
                filters: Yaml.createYamlSequenceBuilder(), predicates: Yaml.createYamlSequenceBuilder()
        ]

        when:
        instance.save().plug(routeElements)
        def yaml = Yaml.createYamlInput(routeElements.filters.build().toString()).readYamlSequence().yamlMapping(0)
        def args = yaml.yamlMapping("args")

        then:
        yaml.string("name") == "RequestRateLimiter"
        args.string("key-resolver") == "\"#{@remoteAddressKeyResolver}\""
        args.string("redis-rate-limiter.replenishRate") == (instance.apiLimit as String)
        args.string("redis-rate-limiter.burstCapacity") == (instance.apiLimit as String)
    }
}
